feat: add TransportOptions for configuring TLS, proxy, and default headers#79
feat: add TransportOptions for configuring TLS, proxy, and default headers#79
Conversation
Introduce a TransportOptions class that encapsulates transport-level configuration (default_headers, ca_cert_path, insecure, proxy_url). Factory methods now accept an optional transport_options parameter alongside the existing individual parameters for backward compatibility. Internal auth plumbing (OpenId, builders) refactored to use TransportOptions throughout.
There was a problem hiding this comment.
Pull request overview
Adds a TransportOptions abstraction to centralize transport-level configuration (default headers, custom CA, insecure TLS, proxy) and threads it through Zitadel client factory methods and auth/OpenID plumbing while preserving backward compatibility with existing keyword args.
Changes:
- Introduce
Zitadel::Client::TransportOptions(plus RBS typings) and update factory APIs to accepttransport_options:alongside individual kwargs. - Extend
Configuration/ApiClientto support per-clientdefault_headersandproxy_urlfor API requests. - Add integration tests (WireMock + Testcontainers) and update README with “advanced configuration” docs.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
lib/zitadel/client/transport_options.rb |
New immutable container for TLS/proxy/header transport settings. |
lib/zitadel/client/zitadel.rb |
Factory methods accept and resolve TransportOptions, apply settings to Configuration. |
lib/zitadel/client/configuration.rb |
Adds default_headers and proxy_url to configuration. |
lib/zitadel/client/api_client.rb |
Merges config.default_headers into request headers; sets Typhoeus proxy option. |
lib/zitadel/client/auth/open_id.rb |
OpenID discovery now honors proxy/CA/insecure/default headers via TransportOptions. |
lib/zitadel/client/auth/authenticator.rb |
OAuth builder now accepts transport_options and passes it to OpenId. |
lib/zitadel/client/auth/client_credentials_authenticator.rb |
Builder accepts transport_options (currently only impacts OpenID discovery). |
lib/zitadel/client/auth/web_token_authenticator.rb |
Builder/from_json accept transport_options (currently only impacts OpenID discovery). |
sig/lib.rbs |
Updates RBS signatures for the new options and new API shapes. |
test/zitadel/client/transport_options_test.rb |
New integration test suite for CA/insecure/headers/proxy init paths. |
README.md |
Documents advanced transport configuration and TransportOptions usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
When a custom CA certificate is configured, the previous implementation set http.ca_file which replaced the system trust store entirely. Now an OpenSSL::X509::Store is used with set_default_paths to load system CAs first, then add_file to include the custom CA alongside them.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Use a pre-generated keystore with proper SANs (localhost, 127.0.0.1, ::1) for WireMock HTTPS instead of extracting certs at runtime. This fixes the hostname mismatch error on systems where localhost resolves to IPv6. Also threads transport options through to OAuth token exchange requests so that custom CA, insecure mode, proxy, and default headers apply end-to-end. Updates RBS type signatures for transport_options parameters.
Assert 201 on stub registration, fix verify_ssl_host for insecure mode, add proxy credential support, consistent with all other SDKs.
Frozen hashes from TransportOptions would raise FrozenError if config or Faraday later tries to mutate the headers hash.
Extract duplicated connection opts construction from authenticators into TransportOptions#to_connection_opts.
Add WireMock stub for settings endpoint and use WireMock's /__admin/requests/count API to assert custom headers are sent on actual API calls, not just during initialization.
Change HTTP library reference from Faraday to Typhoeus and fix the debug example to use the configuration block instead of an unsupported debug: parameter on the factory method.
Factory methods now only accept a TransportOptions object instead of individual default_headers, ca_cert_path, insecure, and proxy_url parameters. This matches the Java and Node SDKs.
WireMock cannot act as an HTTP proxy for OpenID discovery, so use withAccessToken which does not trigger discovery during construction.
Use consistent subsection structure across all SDKs: intro paragraph, then separate sections for TLS, CA cert, headers, and proxy with identical explanatory text.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…on with_access_token, with_client_credentials,\nand with_private_key to match the other SDK implementations.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Align transport options test with the version used in other tests.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Align description with the other SDKs.
Use Testcontainers::DockerContainer and wait_for_tcp_port for the proxy container instead of raw Docker API and custom port-waiting logic.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…nWireMock auto-loads JSON files from /home/wiremock/mappings/ at startup,\nso there is no need to register stubs via the admin API in test setup.
…ppings from fixtures/ to test/fixtures/ to match FIXTURES_DIR,\nand chain with_filesystem_binds calls (method accepts a single argument).
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 20 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| config.default_headers = resolved.default_headers.dup | ||
| config.ssl_ca_cert = resolved.ca_cert_path if resolved.ca_cert_path | ||
| if resolved.insecure | ||
| config.verify_ssl = false | ||
| config.verify_ssl_host = false | ||
| end |
There was a problem hiding this comment.
apply_transport_options sets config.ssl_ca_cert whenever ca_cert_path is present, even when insecure is true. This conflicts with TransportOptions#to_connection_opts (where insecure takes precedence) and can cause Typhoeus/libcurl to try to load a CA file even though TLS verification is disabled. Consider skipping/clearing ssl_ca_cert when resolved.insecure is true so insecure reliably overrides ca_cert_path end-to-end.
Description
This pull request adds support for transport options, allowing users to configure custom CA certificates, disable TLS verification for development environments, route requests through HTTP proxies, and inject default headers (e.g.
Proxy-Authorization) into all SDK requests. A newTransportOptionsclass bundles these four settings into a single reusable object that can be passed to any factory method (with_access_token,with_client_credentials,with_private_key). The existing individual keyword arguments continue to work as before — no breaking changes.Related Issue
N/A
Motivation and Context
Users deploying Zitadel behind corporate proxies, firewalls, or in environments with self-signed or private CA certificates had no clean way to configure these transport-level settings. This change gives them a single object they can construct once with their proxy URL, CA cert path, TLS preferences, and any extra headers, then pass it to whichever authentication method they use.
How Has This Been Tested
test_transport_options_object) verifies that aTransportOptionsinstance can be passed towith_client_credentialsand the SDK initializes successfully against a WireMock HTTPS endpoint.Documentation
The README has been updated with a "Using TransportOptions" subsection under Advanced Configuration.
Checklist